"""Administration form for e-mail settings."""

from __future__ import unicode_literals

import logging

from django import forms
from django.contrib import messages
from django.contrib.sites.models import Site
from django.core.mail import send_mail
from django.utils.translation import ugettext, ugettext_lazy as _
from djblets.mail.message import EmailMessage
from djblets.siteconfig.forms import SiteSettingsForm
from djblets.siteconfig.models import SiteConfiguration

from reviewboard.admin.siteconfig import load_site_config


class EMailSettingsForm(SiteSettingsForm):
    """E-mail settings for Review Board."""

    FROM_SPOOFING_CHOICES = (
        (EmailMessage.FROM_SPOOFING_SMART,
         _('Auto (when allowed by DMARC record)')),
        (EmailMessage.FROM_SPOOFING_ALWAYS, _('Always')),
        (EmailMessage.FROM_SPOOFING_NEVER, _('Never')),
    )

    mail_send_review_mail = forms.BooleanField(
        label=_('Send e-mails for review requests and reviews'),
        required=False)
    mail_send_review_close_mail = forms.BooleanField(
        label=_('Send e-mails when review requests are closed'),
        required=False)
    mail_send_new_user_mail = forms.BooleanField(
        label=_('Send e-mails to administrators when new users register '
                'accounts'),
        required=False)
    mail_send_password_changed_mail = forms.BooleanField(
        label=_('Send e-mails to users when they change their password'),
        required=False)
    mail_enable_autogenerated_header = forms.BooleanField(
        label=_('Enable "Auto-Submitted: auto-generated" header'),
        help_text=_('Marks outgoing e-mails as "auto-generated" to avoid '
                    'auto-replies. Disable this if your mailing list rejects '
                    '"auto-generated" e-mails.'),
        required=False)
    mail_default_from = forms.CharField(
        label=_('Default From address'),
        help_text=_('The e-mail address that all e-mails will be sent from. '
                    'The "Sender" header will be used to make e-mails appear '
                    'to come from the user triggering the e-mail.'),
        required=False,
        widget=forms.TextInput(attrs={'size': '50'}))
    mail_from_spoofing = forms.ChoiceField(
        label=_("Use the user's From address"),
        choices=FROM_SPOOFING_CHOICES,
        required=False,
        help_text=_('Depending on the sender domain\'s DKIM/SPF '
                    'configuration, e-mails may be marked as suspicious when '
                    'sending from the user\'s own e-mail address. '
                    '<strong>Auto</strong> will check the domain\'s DMARC '
                    'record before using their address, falling back to the '
                    '"Default From address" above. <strong>Always</strong> '
                    'will use it unconditionally. <strong>Never</strong> will '
                    'use the default address for every e-mail.'))
    mail_host = forms.CharField(
        label=_('Mail server'),
        required=False,
        widget=forms.TextInput(attrs={'size': '50'}))
    mail_port = forms.IntegerField(
        label=_('Port'),
        required=False,
        widget=forms.TextInput(attrs={'size': '5'}))
    mail_host_user = forms.CharField(
        label=_('Username'),
        required=False,
        widget=forms.TextInput(attrs={'size': '30', 'autocomplete': 'off'}))
    mail_host_password = forms.CharField(
        widget=forms.PasswordInput(attrs={'size': '30', 'autocomplete': 'off'},
                                   render_value=True),
        label=_('Password'),
        required=False)
    mail_use_tls = forms.BooleanField(
        label=_('Use TLS for authentication'),
        required=False)

    send_test_mail = forms.BooleanField(
        label=_('Send a test e-mail after saving'),
        help_text=_('Send an e-mail to yourself using these server settings.'),
        required=False)

    def clean_mail_host(self):
        """Clean the mail_host field.

        This will strip all whitespace around the value.

        Returns:
            unicode:
            The ``mail_host`` field, with all whitespace stripped.
        """
        return self.cleaned_data['mail_host'].strip()

    def save(self):
        """Save the form.

        This will write the new configuration to the database. It will then
        force a site configuration reload.
        """
        super(EMailSettingsForm, self).save()

        # Reload any important changes into the Django settings.
        load_site_config()

        if self.cleaned_data['send_test_mail']:
            site = Site.objects.get_current()
            siteconfig = SiteConfiguration.objects.get_current()

            site_url = '%s://%s' % (siteconfig.get('site_domain_method'),
                                    site.domain)

            if self.request and self.request.user.is_authenticated():
                to_user = self.request.user.email
            else:
                to_user = siteconfig.get('site_admin_email')

            try:
                send_mail(
                    subject=ugettext('E-mail settings test'),
                    message=ugettext('This is a test of the e-mail settings '
                                     'for the Review Board server at %s.')
                            % site_url,
                    mail_from=siteconfig.get('mail_default_from'),
                    recipient_list=[to_user],
                    fail_silently=False)
            except Exception as e:
                messages.error(self.request,
                               ugettext('Failed to send test e-mail.'))
                logging.exception('Failed to send test e-mail: %s', e)

    class Meta:
        title = _('E-Mail Settings')
        save_blacklist = ('send_test_mail',)

        fieldsets = (
            {
                'title': _('E-Mail Notification Settings'),
                'classes': ('wide',),
                'fields': ('mail_send_review_mail',
                           'mail_send_review_close_mail',
                           'mail_send_new_user_mail',
                           'mail_send_password_changed_mail'),
            },
            {
                'title': _('E-Mail Delivery Settings'),
                'classes': ('wide',),
                'fields': ('mail_default_from',
                           'mail_from_spoofing',
                           'mail_enable_autogenerated_header'),
            },
            {
                'title': _('E-Mail Server Settings'),
                'classes': ('wide',),
                'fields': ('mail_host', 'mail_port', 'mail_host_user',
                           'mail_host_password', 'mail_use_tls',
                           'send_test_mail'),
            },
        )
